package com.alogic.lucene.validator;

import com.alogic.lucene.client.IndexerTool;
import com.alogic.lucene.core.ExtAnalyzer;
import com.alogic.lucene.core.Indexer;
import com.alogic.validator.Validator;
import com.anysoft.util.BaseException;
import com.anysoft.util.IOTools;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * 关键词检测
 */
public class KeywordDetector extends Validator.Abstract{
    protected Set<String> keywordDomain = new HashSet<String>();
    protected String field = "default";
    protected String indexerId = "default";

    @Override
    public void configure(Properties p) {
        super.configure(p);
        indexerId = PropertiesConstants.getString(p,"indexerId",indexerId,true);
        field = PropertiesConstants.getString(p,"field",field,true);
        String [] domains = PropertiesConstants.getString(p,"domain","").split(
                PropertiesConstants.getString(p,"delimeter",","));
        for (String domain:domains){
            if (StringUtils.isNotEmpty(domain)){
                keywordDomain.add(domain);
            }
        }
    }

    @Override
    public boolean check(String value, Properties ctx,boolean throwException) {
        boolean result = true;
        Indexer indexer = IndexerTool.getIndexer(indexerId);
        if (indexer != null){
            if (StringUtils.isNotEmpty(value)){
                Analyzer analyzer = indexer.getAnalyzer();
                if (analyzer instanceof ExtAnalyzer) {
                    ExtAnalyzer extAnalyzer = (ExtAnalyzer) analyzer;
                    TokenStream ts = null;
                    try {
                        ts = analyzer.tokenStream(field, value);

                        CharTermAttribute cta = ts.getAttribute(CharTermAttribute.class);
                        TypeAttribute ta = ts.getAttribute(TypeAttribute.class);
                        OffsetAttribute oa = ts.getAttribute(OffsetAttribute.class);

                        ts.reset();
                        while (ts.incrementToken()) {
                            String word = cta.toString();
                            ExtAnalyzer.WordInfo wordInfo = extAnalyzer.getWordInfo(word);
                            if (wordInfo != null && keywordDomain.contains(wordInfo.getDomain())){
                                result = false;
                                break;
                            }
                        }
                    } catch (IOException e) {
                        LOG.error("Failed to analyze text : " + value);
                    } finally {
                        IOTools.close(ts);
                    }
                }
            }
        }
        if (!result && throwException){
            throw new BaseException(getCode(ctx),getMessage(ctx));
        }
        return result;
    }

    @Override
    public boolean check(String value, Properties ctx, Listener listener) {
        boolean result = check(value,ctx,false);
        if (listener != null){
            listener.result(result,value,this,ctx);
        }
        return result;
    }
}